home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK2.toast / Development Kits (Disc 2) / QuickTime™ VR 2.0 SDK / QTVR C⁄C++ Runtime API / Sample Code / VRShell Sample Code / VR3DObjects / Texture.c < prev    next >
Encoding:
Text File  |  1997-05-22  |  6.9 KB  |  281 lines  |  [TEXT/CWIE]

  1. //
  2. //    File:        Texture.c
  3. //
  4. //    Contains:    Support for adding a QuickTime movie or a PICT as a texture on a QD3D object.
  5. //
  6. //    Written by:    Tim Monroe
  7. //                Based (heavily!) on BoxMoov code by Rick Evans and Robert Dierkes
  8. //
  9. //    Copyright:    © 1996 by Apple Computer, Inc., all rights reserved.
  10. //
  11. //    Change History (most recent first):
  12. //
  13. //       <3>         01/14/97    rtm        added support for PICT textures
  14. //       <2>         12/17/96    rtm        modified VR3DTexture_AddToGroup to replace a texture shader
  15. //       <1>         12/16/96    rtm        first file; revised to personal coding style
  16. //       
  17. //
  18. // TODO:
  19.  
  20.  
  21. // header files
  22.  
  23. #include <QuickDraw.h>
  24. #include <Resources.h>
  25.  
  26. #include "QD3D.h"
  27. #include "QD3DGroup.h"
  28. #include "QD3DShader.h"
  29. #include "QD3DSet.h"
  30.  
  31. #include "Texture.h"
  32. #include "TestFunctions.h"
  33.  
  34.  
  35. //////////
  36. //
  37. // VR3DTexture_New
  38. // Create a new texture from a QuickTime movie or PICT file.
  39. //
  40. //////////
  41.  
  42. TextureHdl VR3DTexture_New (Boolean isTextureMovie)
  43. {
  44.     unsigned long        myPictMapAddr;
  45.     GWorldPtr             myGWorld;
  46.     PixMapHandle         myPixMap;
  47.     unsigned long         myPictRowBytes;
  48.     QDErr                myErr;
  49.     GDHandle            myOldGD;
  50.     GWorldPtr            myOldGW;
  51.     Boolean                mySuccess;
  52.     Rect                myBounds;
  53.     TQ3StoragePixmap    *myStrgPMapPtr;
  54.     TextureHdl            myTexture = NULL;
  55.  
  56.     myTexture = (TextureHdl)NewHandleClear(sizeof(Texture));
  57.     if (myTexture == NULL)
  58.         return(myTexture);
  59.         
  60.     HLock((Handle)myTexture);
  61.  
  62.     // save current port
  63.     GetGWorld(&myOldGW, &myOldGD);
  64.         
  65.     if (isTextureMovie) {
  66.         // prompt the user to select a movie;
  67.         // open the movie and store its address in our data structure
  68.         mySuccess = VR3DObjects_GetEmbeddedMovie(&(**myTexture).fMovie);
  69.         if (!mySuccess)
  70.             goto bail;
  71.  
  72.         // get the size of the movie
  73.         GetMovieBox((**myTexture).fMovie, &myBounds);
  74.         
  75.         // create a new offscreen graphics world (into which we will draw the movie)
  76.         myErr = NewGWorld(&myGWorld, 32, &myBounds, 0, 0, useTempMem);
  77.         if (myErr != noErr) {
  78.             StopMovie((**myTexture).fMovie);
  79.             DisposeMovie((**myTexture).fMovie);
  80.             (**myTexture).fMovie = NULL;
  81.             mySuccess = false;
  82.             goto bail;
  83.         }
  84.     } else {
  85.         // prompt the user to select a PICT;
  86.         // open the PICT and store its address in our data structure
  87.         (**myTexture).fPicture = VR3DObjects_GetEmbeddedPicture();
  88.         if ((**myTexture).fPicture == NULL) {
  89.             mySuccess = false;
  90.             goto bail;
  91.         }
  92.         
  93.         // get the size of the picture
  94.         myBounds = (**(**myTexture).fPicture).picFrame;
  95.         
  96.         // create a new offscreen graphics world (into which we will draw the picture)
  97.         myErr = NewGWorld(&myGWorld, 32, &myBounds, 0, 0, useTempMem);
  98.         if (myErr != noErr) {
  99.             KillPicture((**myTexture).fPicture);
  100.             (**myTexture).fPicture = NULL;
  101.             mySuccess = false;
  102.             goto bail;
  103.         }
  104.     }
  105.  
  106.     mySuccess = true;
  107.  
  108.     myPixMap = GetGWorldPixMap(myGWorld);
  109.     LockPixels(myPixMap);
  110.     myPictMapAddr  = (unsigned long)GetPixBaseAddr(myPixMap);
  111.     myPictRowBytes = (unsigned long)(**myPixMap).rowBytes & 0x3fff;
  112.  
  113.     SetGWorld(myGWorld, NULL);
  114.  
  115.     // create a storage object associated with the new offscreen graphics world
  116.     myStrgPMapPtr = &(**myTexture).fStoragePixmap;
  117.     myStrgPMapPtr->image = Q3MemoryStorage_NewBuffer((void *)myPictMapAddr,
  118.                                                     myPictRowBytes * myBounds.bottom,
  119.                                                     myPictRowBytes * myBounds.bottom);
  120.     myStrgPMapPtr->width        = myBounds.right;
  121.     myStrgPMapPtr->height        = myBounds.bottom;
  122.     myStrgPMapPtr->rowBytes        = myPictRowBytes;
  123.     myStrgPMapPtr->pixelSize    = 32;
  124.     myStrgPMapPtr->pixelType    = kQ3PixelTypeRGB32;
  125.     myStrgPMapPtr->bitOrder        = kQ3EndianBig;
  126.     myStrgPMapPtr->byteOrder    = kQ3EndianBig;
  127.  
  128.     if (isTextureMovie) {
  129.         // start playing the movie in a loop
  130.         VR3DObjects_LoopEmbeddedMovie((**myTexture).fMovie, myGWorld);
  131.     } else {
  132.         // draw the picture into the offscreen graphics world
  133.         DrawPicture((**myTexture).fPicture, &myBounds);
  134.     }
  135.  
  136.     (**myTexture).fpGWorld = myGWorld;
  137.  
  138. bail:
  139.     SetGWorld(myOldGW, myOldGD);
  140.  
  141.     HUnlock((Handle)myTexture);
  142.  
  143.     if (mySuccess)
  144.         return(myTexture);
  145.     else
  146.         return(NULL);
  147. }
  148.  
  149.  
  150. //////////
  151. //
  152. // VR3DTexture_AddToGroup
  153. // Create a new texture shader based on the pixmap storage data and add it to the group.
  154. //
  155. //////////
  156.  
  157. TQ3Status VR3DTexture_AddToGroup (TextureHdl theTexture, TQ3GroupObject theGroup)
  158. {
  159.     TQ3Status            myStatus = kQ3Failure;
  160.     TQ3StoragePixmap    myStoragePixmap;
  161.     TQ3TextureObject    myTextureObject;
  162.     
  163.     if (theTexture == NULL || theGroup == NULL)
  164.         return(myStatus);
  165.     
  166.     myStoragePixmap = (**theTexture).fStoragePixmap;
  167.     myTextureObject = Q3PixmapTexture_New(&myStoragePixmap);
  168.     if (myTextureObject != NULL) {
  169.  
  170.         TQ3ShaderObject        myTextureShader;
  171.         
  172.         myTextureShader = Q3TextureShader_New(myTextureObject);
  173.         Q3Object_Dispose(myTextureObject);
  174.         
  175.         if (myTextureShader != NULL) {
  176.             TQ3GroupPosition    myPosition = NULL;
  177.             
  178.             // look for an existing texture shader in group
  179.             Q3Group_GetFirstPositionOfType(theGroup, kQ3SurfaceShaderTypeTexture, &myPosition);
  180.             if (myPosition != NULL) {
  181.             
  182.                 // there is an existing texture shader; just replace it
  183.                 Q3Group_SetPositionObject(theGroup, myPosition, myTextureShader);
  184.             } else {
  185.             
  186.                 // there is no existing texture shader; add one to the group
  187.                 Q3Group_GetFirstPosition(theGroup, &myPosition);
  188.                 Q3Group_AddObjectBefore(theGroup, myPosition, myTextureShader);
  189.             }
  190.             
  191.             Q3Object_Dispose(myTextureShader);
  192.             myStatus = kQ3Success;
  193.         }
  194.     }
  195.  
  196.     return(myStatus);
  197. }
  198.  
  199.  
  200. //////////
  201. //
  202. // VR3DTexture_Delete
  203. // Deallocate the texture.
  204. //
  205. //////////
  206.  
  207. Boolean    VR3DTexture_Delete (TextureHdl theTexture)
  208. {
  209.     if (theTexture == NULL)
  210.         return(false);
  211.  
  212.     if ((**theTexture).fpGWorld == NULL)
  213.         return(false);
  214.  
  215.     HLock((Handle)theTexture);
  216.  
  217.     if ((**theTexture).fMovie != NULL) {
  218.         StopMovie((**theTexture).fMovie);
  219.         DisposeMovie((**theTexture).fMovie);
  220.         (**theTexture).fMovie = NULL;
  221.     }
  222.  
  223.     if ((**theTexture).fPicture != NULL) {
  224.         KillPicture((**theTexture).fPicture);
  225.         (**theTexture).fPicture = NULL;
  226.     }
  227.  
  228.     DisposeGWorld((**theTexture).fpGWorld);
  229.     (**theTexture).fpGWorld = NULL;
  230.  
  231.     if ((**theTexture).fStoragePixmap.image != NULL) {
  232.         Q3Object_Dispose((**theTexture).fStoragePixmap.image);
  233.         (**theTexture).fStoragePixmap.image = NULL;
  234.     }
  235.  
  236.     HUnlock((Handle)theTexture);
  237.     DisposeHandle((Handle)theTexture);
  238.     return(true);
  239. }
  240.  
  241.  
  242. //////////
  243. //
  244. // VR3DTexture_NextFrame
  245. // Advance the texture's movie to the next frame.
  246. //
  247. //////////
  248.  
  249. Boolean VR3DTexture_NextFrame (TextureHdl theTexture)
  250. {
  251.     TQ3StoragePixmap    *myStrgPMapPtr;
  252.     PixMapPtr            myPixMap;
  253.     long                mySize;
  254.     TQ3Status            myStatus;
  255.  
  256.     // if fpGWorld is non-NULL then the fMovie is non-NULL and the movie needs updating
  257.     if ((**theTexture).fpGWorld == NULL)
  258.         return(false);
  259.  
  260.     HLock((Handle)theTexture);
  261.  
  262.     if ((**theTexture).fMovie) {
  263.         MoviesTask((**theTexture).fMovie, 0);    // draw the next movie frame
  264.     }
  265.  
  266.     myStrgPMapPtr = &(**theTexture).fStoragePixmap;
  267.  
  268.     // tell QD3D the buffer changed
  269.     myPixMap = *((**theTexture).fpGWorld)->portPixMap;
  270.     mySize = myStrgPMapPtr->height * myStrgPMapPtr->rowBytes;
  271.  
  272.     myStatus = Q3MemoryStorage_SetBuffer(myStrgPMapPtr->image, (void *)myPixMap->baseAddr, mySize, mySize);
  273.  
  274.     HUnlock((Handle)theTexture);
  275.     
  276.     if (myStatus == kQ3Success)
  277.         return(true);
  278.     else
  279.         return(false);
  280. }
  281.